<template>
  <div class="department-container">
    <div class="app-container">
      <!-- 面板结构 -->
      <el-card>
        <!-- 头部 -->
        <!-- 行列布局：栅格布局，将一行分为 24 份，每列占多少份由 el-col 身上的 span 属性决定。 -->
        <!-- type：flex 启用弹性布局。默认是使用的浮动布局 -->
        <!-- justify：flex 布局下的水平排列方式 -->
        <!-- align：flex 布局下的垂直排列方式 -->
        <treeTools :item="company" :is-root="true" @showEdit="showEdit" />
        <!-- data是树形组件的传入的数据 是一个数组 带有层级关系 (通过children体现) -->
        <!-- show-checkbox 节点是否可被选择 -->
        <!-- node-key 每个树节点用来作为唯一标识的属性，整棵树应该是唯一的 类似于v-for中的key -->
        <!-- default-expand-all 是否默认展开所有节点 -->
        <!-- expand-on-click-node 点击箭头 还是点击文字用于收起展开 -->
        <!-- el-tree对于传入的数据的键名有固定要求 默认用于显示的字段 label  -->
        <!-- 默认用于显示层级的字段键名只能为children -->
        <!-- props 是一个对象 在对象中可以配置 树形组件用于渲染文字的字段名 label
        也可以配置 树形组件用于定义层级关系的字段名 children -->
        <el-tree
          :data="list"
          node-key="id"
          default-expand-all
          :props="defaultProps"
        >
          <template #default="{data}">
            <treeTools :item="data" @showEdit="showEdit" />
          </template>
        </el-tree>
      </el-card>
    </div>
    <el-dialog
      :title="title"
      :visible="dialogVisible"
      width="50%"
      @close="closeDialog"
    >
      <!-- ------------ -->
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="部门名称" prop="name">
          <el-input v-model="form.name" placeholder="1-50个字符" />
        </el-form-item>

        <el-form-item label="部门编码" prop="code">
          <el-input v-model="form.code" placeholder="1-50个字符" />
        </el-form-item>

        <el-form-item label="部门负责人" prop="manager">
          <el-select v-model="form.manager" placeholder="请选择" style="width:100%">
            <el-option
              v-for="item in empolyeeList"
              :key="item.id"
              :label="item.username"
              :value="item.username"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="部门介绍" prop="introduce">
          <el-input v-model="form.introduce" type="textarea" placeholder="1-300个字符" />
        </el-form-item>
      </el-form>

      <!-- ------------ -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submit">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import treeTools from '@/views/Department/components/tree-tools.vue'
import { getDepartmentList, addDepartment, getDetailById, updateDepartment, delDepartmentById } from '@/api/department'
import { getSimpleList } from '@/api/employee'
export default {
  name: 'Department',
  components: {
    treeTools
  },
  data() {
    // 不能出现相同的部门名称
    const validateName = (rule, value, callback) => {
      // if (value === 'yanyibo') {
      //   return callback(new Error('不能写老板名字!!!'))
      // } else {
      //   callback()
      // }
      let broArr = []
      // 在编辑中 部门名称不能和他的兄弟们名字一样
      if (this.form.id) {
      // 在编辑中
        if (value === this.currentNode.name) {
          // 此时没有修改任何 直接callback() return
          callback()
        } else {
          // 此时修改了内容
          // 如果是编辑找的是当前节点的兄弟节点
          broArr = this.rowList.filter(item => item.pid === this.currentNode.pid)
        }
      } else {
      // 如果是新增子部门 找到的当前节点下的子节点才是新增子部门的 兄弟节点
        broArr = this.rowList.filter(item => item.pid === this.currentNode.id)
      //
        // const broArr = this.rowList.filter(item => item.pid === this.currentNode.id)
      }
      const isSome = broArr.some(item => item.name === value)
      if (isSome) {
        return callback(new Error('名字重复'))
      } else {
        callback()
      }
    }
    // 所有部门不能出现相同编码
    const validateCode = (rule, value, callback) => {
      if (this.form.id && value === this.currentNode.code) {
        callback()
      } else {
        const isSame = this.rowList.some(item => item.code === value)
        if (isSame) {
          return callback(new Error('不能出现重复的部门编码'))
        } else {
          callback()
        }
      }
    }
    return {
      defaultProps: {
        label: 'name',
        children: 'children'
      },
      company: {
        name: '传智播客',
        manger: '负责人',
        // 兼容公司下新增根部门 添加一个id值为空字符串
        id: ''
      },
      list: [],
      dialogVisible: false,
      form: {
        code: '',
        introduce: '',
        manager: '',
        name: ''
      },
      // 自定义校验

      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门名称要求1-50个字符', trigger: ['blur', 'change'] },
          { validator: validateName, trigger: blur }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门编码要求1-50个字符', trigger: ['blur', 'change'] },
          { validator: validateCode, trigger: blur }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: ['blur', 'change'] }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 300, message: '部门介绍要求1-300个字符', trigger: ['blur', 'change'] }
        ]
      },
      // 获取当前点击事件触发的对象
      currentNode: {},
      // 储存全部数据
      rowList: [],
      empolyeeList: []
    }
  },
  computed: {
    title() {
      return this.form.id ? '编辑部门' : '新增部门'
    }
  },
  created() {
    this.getList()
  },
  methods: {
    async getList() {
      const res = await getDepartmentList()
      // console.log(res)
      this.list = this.findChildren(res.data.depts, '')
      this.rowList = res.data.depts
    },
    findChildren(arr, id = '') {
      const children = []
      arr.forEach(item => {
        if (item.pid === id) {
          children.push(item)
          if (children.length) {
            item.children = this.findChildren(arr, item.id)
          }
        }
      })
      return children
    },
    // 打开弹窗
    async showEdit(item, type) {
      if (type === 'del') {
        this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消'
        }).then(async() => {
          await delDepartmentById(item.id)
          this.$message({
            type: 'success',
            message: '删除成功!'
          })
          this.getList()
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
        return
      }
      this.dialogVisible = true
      // console.log(item, '当前操作的节点')
      this.currentNode = item
      // 打开弹窗调用接口
      // 新增 和 编辑 两种type判断执行
      if (type === 'edit') {
        const res1 = await getDetailById(item.id)
        this.form = res1.data
      }
      const res = await getSimpleList()
      // console.log(res)
      this.empolyeeList = res.data
    },
    // 关闭弹窗
    closeDialog() {
      this.dialogVisible = false
      // 每次关闭都要重置
      this.$refs.formRef.resetFields()
      // 手动重置
      this.form = {
        code: '',
        introduce: '',
        manager: '',
        name: ''
      }
    },
    // 新建部门
    async submit() {
      const valid = await this.$refs.formRef.validate()
      if (valid) {
        // 1 准备接口参数
        // 2 调用接口
        // 根据this.form中是否有id区分新增和修改
        if (this.form.id) {
          // 修改
          await updateDepartment(this.form)
        } else {
          await addDepartment({
            ...this.form,
            pid: this.currentNode.id
          })
        }

        // 关闭弹窗
        // this.dialogVisible = false
        // 提示用户
        this.$message.success(`${this.title}成功`)
        // 刷新列表
        this.getList()
        // 重置并关闭表单
        this.closeDialog()
      }
    }
    // 编辑部门数据回显  (封装了一个type属性 在showEdit里做判断了)
    // async editDepartment(item) {
    //   this.currentNode = item
    //   const res = await getDetailById(item.id)
    //   this.form = res.data
    //   this.dialogVisible = true
    //   // 打开弹窗调用接口
    //   const res1 = await getSimpleList()
    //   console.log(res1)
    //   this.empolyeeList = res1.data
    // }
  }
}
</script>

<style lang="scss" scoped>
.department-container {
  padding: 30px;
}
</style>
